
#region Imported Namespaces
using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections;

using BO = PHSRAG.Insight21.BusinessObjects;
using DataAccess = PHSRAG.Utility.DataAccess;
using Utility = PHSRAG.Utility;
using ICachePolicy = PHSRAG.Insight21.Policy.ICachePolicy;
# endregion

namespace PHSRAG.Insight21.Humans
{
	/// <summary>
	/// This LogItem abstracts the notion of the errors occurred during the validation of the Protocol submission process 
	/// </summary>
		
	public class LogItem :BO.SmartBusinessObject
	{
		#region Constants
		/// <summary>LogItem Key</summary>
		private const string LogItemKey="LogItem_242F5381-21A1-49a4-AF3F-E4083D693C29";
		/// <summary>LogItem dataTable name</summary>
		private const string LogItemDataTableName="LogItem";
		/// <summary>LogItem dataTable columns</summary>
			/// <summary>Constant specifying the LogItemId column</summary>
			private const string columnId = "Id";
			/// <summary>Constant specifying the LogItem Description column</summary>
			private const string columnDescription="Description";
			/// <summary>Constant specifying the Questionnaire version Id column</summary>
			private const string columnQuestionnaireVersionId = "QuestionnaireVersionId";
			/// <summary>Constant specifying the Questionnaire answer Id column</summary>
			private const string columnQuestionnaireAnswerId = "QuestionnaireAnswerId";
			/// <summary>Constant specifying the LogItem Type column</summary>
			private const string columnType = "Type";
			/// <summary>Constant specifying the LogItem's question name column</summary>
			private const string columnQuestionName = "QuestionName";
			/// <summary>Constant specifying the LogItem's Answer column</summary>
			private const string columnAnswer = "Answer";
			/// <summary>Constant specifying the staus of LogItem column </summary>
			private const string columnCompleted = "Completed";
		/// <summary>Constant specifying the category of LogItem </summary>
		private const string columnCategory = "Category";
		#endregion
	
		#region private instance variables
		/// <summary>Variable that holds the Log Item Description</summary>
		private string description;
		/// <summary>Variable that holds the questionnaire version Id</summary>
		private int questionnaireVersionId ;
		/// <summary>Variable that holds the questionnaire answer Id</summary>
		private int questionnaireAnswerId ;
		/// <summary>Variable that holds the Log Item type</summary>
		private string type ;
		/// <summary>Variable that holds the Log Item's question name</summary>
		private string questionName;
		/// <summary>Variable that holds the Log Item' answer</summary>
		private string answer;
		/// <summary>Variable that holds the Log Item category</summary>
		private string category;
		/// <summary>Variable that holds the Log Item status</summary>
		private bool completed;
		#endregion

		#region public properties
		
		/// <summary>
		/// Cache Key uniquely identifies this object within the cache.
		/// </summary>
		/// <returns>the unique string for this object.</returns>
		public override string CacheKey()
		{
			return LogItemKey;
		}
		
		/// <summary>Property to get / set the description of the Log item</summary>
		public string Description
		{
			get{return description;}
			set{SetDirty(ref description , value);
			}
		}
		/// <summary>Property to get / set the Log Item type</summary>
		public string Type
		{
			get{return type;}
			set{SetDirty(ref type , value);}
		}
		/// <summary>Property to get / set the questionnairVersionId</summary>
		public int QuestionnaireVersionId
		{
			get{return questionnaireVersionId;}
			set{SetDirty(ref questionnaireVersionId , value);}
		}
		/// <summary>Property to get / set the questionnairAnswerId</summary>
		public int QuestionnaireAnswerId
		{
			get{return questionnaireAnswerId;}
			set{SetDirty(ref questionnaireAnswerId , value);}
		}
		/// <summary>Property to get / set the questionName</summary>
		public string QuestionName
		{
			get{return questionName;}
			set{SetDirty(ref questionName , value);}
		}
		/// <summary>Property to get / set the answer</summary>
		public string Answer
		{
			get{return answer;}
			set{SetDirty(ref answer , value);}
		}
		/// <summary>Property to get / set the category</summary>
		public string Category
		{
			get{return category;}
			set{SetDirty(ref category , value);}
		}
		/// <summary>Property to get / set the completed</summary>
		public bool Completed
		{
			get{return completed;}
			set{SetDirty(ref completed , value);}
		}
		#endregion

		#region Caching
		/// <summary>
		/// Cache this instance using the prevalent cache policy.
		/// </summary>
		public override void Cache()
		{
			CachePolicy.Cache(CacheKey(), this);
		}

		/// <summary>
		/// Remove this instance from the cache using the prevalent cache policy.
		/// </summary>
		public override void UnCache()
		{
			CachePolicy.UnCache(CacheKey());
		}
		#endregion

		#region Private methods
		/// <summary>
		/// Populate the logItem members with the datarow passed in as parameter
		/// </summary>
		/// <param name="row">Datarow containing the values for the LogItem properties</param>
		private void PopulateMembers(DataRow row)
		{
			Id=						(int)row[columnId];
			object o=				 row[columnDescription];
			description=			(o==DBNull.Value)? string.Empty : (string)row[columnDescription];
			questionnaireVersionId=	(int)row[columnQuestionnaireVersionId];
			questionnaireAnswerId=	(int)row[columnQuestionnaireAnswerId];
			o=						 row[columnType];
			type=					(o==DBNull.Value)? string.Empty :(string)o;
			o=						 row[columnQuestionName];
			questionName=			(o==DBNull.Value)? string.Empty :(string)o;
			o=						 row[columnAnswer];
			answer=					(o==DBNull.Value)? string.Empty :(string)o;
			o=						 row[columnCategory];
			category=				(o==DBNull.Value)? string.Empty :(string)o;
			completed=				(bool)row[columnCompleted];
		}
		#endregion

		#region constructors
		/// <summary>
		/// Constructs a new LogItem object based on the Cache Policy passed in as a parameter. 
		/// All the instance variables will be set to default values of their associated types.
		/// </summary>
		/// <param name="cachePolicy">available cahche policy</param>
		public LogItem(ICachePolicy cachePolicy): base(cachePolicy)
		{
			
		}
		/// <summary>
		/// Constructs a new LogItem object based on the Cache Policy  and the datarow passed in as a parameter. 
		/// All the instance variables will be set to the values from the datarow.
		/// </summary>
		/// <param name="cachePolicy">available cache Policy</param>
		/// <param name="dataRow">The datarow passses in as parameter</param>
		public LogItem(ICachePolicy cachePolicy ,DataRow logItemRow): base(cachePolicy)
		{
			PopulateMembers(logItemRow);
		}

		/// <summary>
		/// Constructs a new LogItem object and initializes it with the provided values
		/// </summary>
		/// <param name="cachePolicy">available cahche policy</param>
		/// <param name="answer">if non-empty; the answer that the user provided that is causing error</param>
		/// <param name="category">not currently used, but we are maintaining in the db</param>
		/// <param name="description">message that will be displayed to the user to indicate error -->
		/// this is the validation message provided in the forms tool OR a hard-coded message in the
		/// validation script if there is no validation message in the tool (e.g. a missing form)</param>
		/// <param name="questionnaireVersionId">id of the questionnaire version the user originally
		/// was presented with (so that we can pull the correct version if we need to present them with
		/// the form again)</param>
		/// <param name="type">this shows up on the Protocol Submission page under Form/Type column
		/// --> If it's a form, it should say the form name</param>
		/// <param name="questionname">If non-empty, the name of the question causing error (if it is an
		/// entire form the user didn't answer, e.g., this will be empty</param>
		/// <param name="completed">if the logItem has been resolved</param>
		/// <param name="questionnaireAnswerId">the id of the answer the user provided</param>
		/// <param name="processId"></param>
		/// 
		/// <remarks>The QuestionnaireVersionId is used to redirect the user to the appropriate screen upon
		/// clicking on the logitem (e.g. a certain flag indicates to redirect to the attachments page) 
		/// and the QuestionnaireAnswerId is used to load up the answers to that questionnaire previously
		/// provided by the user, for modification (if required)</remarks>
		public LogItem(ICachePolicy cachePolicy, int processId, int questionnaireVersionId,
			int questionnaireAnswerId, string type, string category, string questionname,
			string answer, string description, bool completed): base(cachePolicy)
		{
			this.QuestionnaireVersionId = questionnaireVersionId;
			this.QuestionnaireAnswerId = questionnaireAnswerId;
			this.Type = type;
			this.Category = category;
			this.QuestionName = questionname;
			this.Answer = answer;
			this.Description = description;
			this.Completed = completed;
		}

		#endregion

		#region Saveable overriden Business Object Methods

		/// <summary>
		/// override for DeleteObject will clear the log Items. 
		/// Method not implemented,when called will throw exception.
		/// </summary>
		/// <param name="sqlTransaction">SQL transaction to use when deleting.</param>
		protected override void DeleteObject( SqlTransaction sqlTransaction)
		{
			throw new Exception("LogItem.DeleteObject is not implemented.");
		}


		/// <summary>
		///  override for saveobject only saves the business object's data members (only those members which contribute to the 
		/// dirty state). This is called in the public Save method, if the object is determined to be 
		/// dirty and need saving.
		/// </summary>
		/// <param name="sqlTransaction">transaction passed in to do the saving on.</param>>
		protected override void SaveObject(SqlTransaction sqlTransaction)
		{
			try
			{
				Id = Convert.ToInt32(Utility.DataAccess.ExecuteScalar(sqlTransaction.Connection,sqlTransaction,"SaveLogItem",Utility.DataAccess.BuildSqlParameterArray(
					"@id",SqlDbType.Int,Id
					,"@questionnaireVersionId",SqlDbType.Int,questionnaireVersionId
					,"@questionnaireAnswerId",SqlDbType.Int,questionnaireAnswerId
					,"@type",SqlDbType.VarChar,type
					,"@category",SqlDbType.VarChar,category
					,"@questionName",SqlDbType.VarChar,questionName
					,"@answer",SqlDbType.VarChar,answer
					,"@description",SqlDbType.VarChar,Description
					,"@completed",SqlDbType.Bit,completed)));
			}
			catch(Exception e)
			{
				Utility.ExceptionReport.WriteToEventLog ("Failed to save LogItem, error occurred in logItem.SaveObject();", e, true, Utility.ExceptionReport.ReportType.Error);
				throw;
			}
		}

		#endregion

		#region Overrides
		// <summary>
		/// Determine whether or not the LogItem is dirty , based  on
		/// whether is's properties have changed (making it dirty), or any of its 
		/// contained business objects are dirty .
		/// </summary>
		/// <returns>true if it is dirty, false if not dirty.</returns>
		/// 
		public override bool IsDirty()
		{
			if ( Dirty )
				return true;
			else return false;

		}

		/// <summary>
		/// Override for Load method :Load the log Item members with the correspponding values obtained from the DB
		/// by passing the logItem Id as parameter.
		/// </summary>
		/// <param name="connectionString">Database connection string</param>
		/// <param name="args"> collection of parameters</param>
		public override void Load(string connectionString, params object[] args)
		{
			if ( args.Length != 1 )
				throw new Exception("LogItem load expects LogIem Id as a parameter.");

			try
			{
				DataSet LogItemDS = new DataSet();
				Utility.DataAccess.LoadDataSet(LogItemDS, LogItemDataTableName, connectionString, "GetLogItem", 
					Utility.DataAccess.BuildSqlParameterArray(
											"@id", SqlDbType.Int, (int)args[0]));
				
				DataTable table = LogItemDS.Tables[LogItemDataTableName];
				foreach (DataRow logItemRow in  table.Rows)
				{
					PopulateMembers(logItemRow);
				}
			}
			catch( Exception e)
			{
				Utility.ExceptionReport.WriteToEventLog ("Failed to load LogItem , error occurred at logItem.Load(); ", e, true, Utility.ExceptionReport.ReportType.Error);
				throw;
			}
		}

		#endregion

		#region public methods
        /// <summary>
        /// Get all the logItems tied with protocolProcess using protocolProcessId
        /// </summary>
        /// <param name="protocolProcessId">Protocol Process Id</param>
        /// <param name="cachePolicy">CachePolicy</param>
        /// <returns>ArrayList of LogItem</returns>
		public static ArrayList GetLogItems(int protocolProcessId,ICachePolicy cachePolicy)
		{
			try
			{

				DataTable logItemDataTable = new DataTable();
				Utility.DataAccess.LoadDataTable(logItemDataTable, Utility.DataAccess.GetConnectionString(), "GetLogItemsForProcess", 
										Utility.DataAccess.BuildSqlParameterArray(
										"@protocolProcessId", SqlDbType.Int, protocolProcessId));
				
				//Count=logItemDataTable.Rows.Count;
				ArrayList logItemList=new ArrayList();
				LogItem logItem;
				foreach (DataRow logItemRow in logItemDataTable.Rows)
				{
					logItem=new LogItem(cachePolicy,logItemRow);
					logItemList.Add(logItem);
				}
				return logItemList;
			}
			catch( Exception e)
			{
				Utility.ExceptionReport.WriteToEventLog ("Failed to get the Log items, error occurred at logItem.GetLogItems();", e, true, Utility.ExceptionReport.ReportType.Error);
				throw;
			}
		}
		/// <summary>
		/// Get all the logItems tied with protocolProcess using protocolProcessId
		/// </summary>
		/// <param name="protocolProcessId">Protocol Process Id</param>
		/// <param name="cachePolicy">CachePolicy</param>
		/// <returns>ArrayList of LogItem</returns>
		public static ArrayList GetLogItemsForCOI(int coiId,ICachePolicy cachePolicy)
		{
			try
			{

				DataTable logItemDataTable = new DataTable();
				Utility.DataAccess.LoadDataTable(logItemDataTable, Utility.DataAccess.GetConnectionString(), "GetLogItemsForCOI",
					Utility.DataAccess.BuildSqlParameterArray(
					"@coiId", SqlDbType.Int, coiId));
				
				//Count=logItemDataTable.Rows.Count;
				ArrayList logItemList=new ArrayList();
				LogItem logItem;
				foreach (DataRow logItemRow in logItemDataTable.Rows)
				{
					logItem=new LogItem(cachePolicy,logItemRow);
					logItemList.Add(logItem);
				}
				return logItemList;
			}
			catch( Exception e)
			{
				Utility.ExceptionReport.WriteToEventLog ("Failed to get the Log items, error occurred at logItem.GetLogItemsForCOI();", e, true, Utility.ExceptionReport.ReportType.Error);
				throw;
			}
		}
		#endregion
	}
}
